//
//  CircularLoaderView.m
//  ImageLoaderIndicatorDemo
//
//  Created by 卢小辉 on 15/10/16.
//  Copyright © 2015年 lulee007. All rights reserved.
//

#import "CircularLoaderView.h"
#define CircleRadius 20.0f

@implementation CircularLoaderView

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (instancetype)initWithFrame:(CGRect)frame{
    self=[super initWithFrame:frame];
    if(self){
        [self configure];
    }
    return self;
    
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder{
    self=[super initWithCoder:aDecoder];
    if(self){
        [self configure];
    }
    return self;
}
//override
- (void)layoutSubviews{
    [super layoutSubviews];
    self.circlePathLayer.frame=self.bounds;
    self.circlePathLayer.path=[self buildCirclePath].CGPath;
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    self.superview.layer.mask=nil;
}


//public

-(CGFloat)progress{
    return self.circlePathLayer.strokeEnd;
}

- (void)setProgress:(CGFloat)progress{
    if(progress>1){
        self.circlePathLayer.strokeEnd=1;
    }else if(progress<0){
        self.circlePathLayer.strokeEnd=0;
    }else{
        self.circlePathLayer.strokeEnd=progress;
    }
}

- (void)reveal{
    /*
     
    1、 确定圆形的半径之后就能完全限制image view。然后计算CGRect来完全限制这个圆形。toPath表示CAShapeLayer mask的最终形状。
    2、 设置lineWidth和path初始值来匹配当前layer的值。
    3、 设置lineWidth和path的最终值；这样能防止它们当动画完成时跳回它们的原始值。CATransaction设置kCATransactionDisableActions键对应的值为true来禁用layer的implicit animations。
    4、 创建一个两个CABasicAnimation的实例，一个是路径动画，一个是lineWidth动画，lineWidth必须增加到两倍跟半径增长速度一样快，这样圆形向内扩展与向外扩展一样。
    5、 将两个animations添加到一个CAAnimationGroup，然后添加animation group到layer。将self赋值给delegate，等下你会使用到它。
     */
    
    self.backgroundColor=[UIColor clearColor];
    self.progress=1;
    [self.circlePathLayer removeAnimationForKey:@"strokeEnd"];
    [self.circlePathLayer removeFromSuperlayer];
//    self.circlePathLayer.fillColor =[UIColor blackColor].CGColor;
    self.superview.layer.mask=self.circlePathLayer;
    
    
    //1
    CGPoint center=CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    CGFloat finalRadius=sqrt((center.x*center.x )+(center.y*center.y));
    CGFloat radiusInset=finalRadius-CircleRadius;
    CGRect outerRect=CGRectInset([self buildCircleFrame], -radiusInset, -radiusInset);
    CGPathRef toPath=[UIBezierPath bezierPathWithOvalInRect:outerRect].CGPath;
    //2
    CGPathRef fromPath=self.circlePathLayer.path;
    CGFloat fromLineWidth=self.circlePathLayer.lineWidth;
    
    //3
    [CATransaction begin];
//    [CATransaction setValue:  kCFBooleanTrue forKey:kCATransactionDisableActions];
    self.circlePathLayer.lineWidth=2.0f*finalRadius;
    self.circlePathLayer.path=toPath;
    [CATransaction commit];

    
    //4
    CABasicAnimation *lineWidthAnimation=[CABasicAnimation animation];
    [lineWidthAnimation setKeyPath:@"lineWidth"];
    lineWidthAnimation.fromValue=[NSNumber numberWithFloat:fromLineWidth];
    lineWidthAnimation.toValue=[NSNumber numberWithFloat:2.0f*finalRadius];
    CABasicAnimation *pathAnimation=[CABasicAnimation animation];
    [pathAnimation setKeyPath:@"path"];
    pathAnimation.fromValue = (__bridge id _Nullable)((fromPath));
    pathAnimation.toValue = (__bridge id _Nullable)((toPath));
    
    
    //5
    CAAnimationGroup * groupAnimation=[[CAAnimationGroup alloc]init];
    groupAnimation.duration=0.5f;
    groupAnimation.timingFunction=[CAMediaTimingFunction  functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    groupAnimation.animations=@[pathAnimation, lineWidthAnimation];
    groupAnimation.delegate=self;
    [self.circlePathLayer addAnimation:groupAnimation forKey:@"strokeWidth"];
}

//private
-(void) configure{
    self.circlePathLayer=[[CAShapeLayer alloc]init];
    self.circlePathLayer.frame=self.bounds;
    self.circlePathLayer.lineWidth=2.0f;
    self.circlePathLayer.fillColor=[UIColor clearColor].CGColor;
    self.circlePathLayer.strokeColor=[UIColor redColor].CGColor;
    self.progress=0;
    [self.layer addSublayer:self.circlePathLayer];
    self.backgroundColor=[UIColor whiteColor];
}

-(CGRect) buildCircleFrame{
    CGRect circleFrame=CGRectMake(0, 0, 2.0*CircleRadius, 2.0*CircleRadius);
    circleFrame.origin.x=CGRectGetMidX(self.circlePathLayer.bounds)-CGRectGetMidX(circleFrame);
    circleFrame.origin.y=CGRectGetMidY(self.circlePathLayer.bounds)-CGRectGetMidY(circleFrame);
    
    return circleFrame;
}

-(UIBezierPath *) buildCirclePath{
   return [UIBezierPath bezierPathWithOvalInRect:[self buildCircleFrame]];
}

@end
